<template>
  <div class="b-box" @mousemove.once="handleMousemove">
    <div class="devices-icon" v-show="showBox" @mousedown="handleActiveChange">
      <template v-for="item in devices" :key="item">
        <div :class="[getIcon(item.deviceType)]" class="devices-icon-item iconfont" v-if="filterShow(item.deviceType)">
          <div v-if="isIconAlarm(item.deviceIdList)"
            :class="[{ isAlarm: isIconAlarm(item.deviceIdList) }, getIcon(item.deviceType)]"
            class="devices-icon-item iconfont">
          </div>
        </div>
      </template>
    </div>

    <div class="devices-body" :class="{ active: active && showBox }">
      <div class="devices-body-name">
        {{ info.name }}
        <el-icon @mousedown="handleClose">
          <CloseBold />
        </el-icon>
      </div>
      <div class="devices-content">
        <div class="devices-content-video" v-if="filterShow('003') && info.cameraList.length">
          <template v-for="camera in info.cameraList" :key="camera.cameraUuid">
            <el-image @mousedown="showVideoDialog(camera)" class="devices-content-video-item"
              :src="`${BASE_URL}video/getPlaySnap?cameraUuid=${camera.cameraUuid}&customerNo=${camera.customerNo}&cameraType=${camera.cameraType}`">
              <template #error>
                <el-icon size="32">
                  <VideoPlay />
                </el-icon>
              </template>
            </el-image>
          </template>
        </div>
        <div class="devices-content-baseStation" v-if="filterShow('001') && info.jzList.length">
          <div class="devices-content-baseStation-item" @mousedown="showAreaDialog(item)" v-for="item in info.jzList"
            :key="item.jzUuid">
            <div class="devices-content-sensor-item-name">
              基站名称:
            </div>
            <div class="devices-content-sensor-item-value" :title="item.jzName">{{ item.jzName }}</div>
          </div>
        </div>
        <div class="devices-content-sensor" v-if="filterShow('002') && sensorListFilter.length">
          <div class="devices-content-sensor-item" @mousedown="showSensorDialog(item)"
            :class="{ isAlarm: alarms.some(node => node.cdCode === item.cdCode), isInlen: ['1004', '1010'].includes(item.sensorType) }"
            v-for="item in (globalParams.areaId ? hisSensorList : sensorListFilter)" :key="item.cdCode">
            <template v-if="['1004', '1010'].includes(item.sensorType)">
              <b-fan :status="item.showValue" :name="item.areaLocation"></b-fan>
            </template>
            <template v-else>
              <div class="devices-content-sensor-item-name" :title="item.areaLocation">
                {{ extractDifferentPart(info.name, item.areaLocation) }}:
              </div>
              <div class="devices-content-sensor-item-value">{{ item.showValue || '--' }}</div>
              <el-icon v-if="alarms.some(node => node.cdCode === item.cdCode)" @mousedown.stop="showAlarmDetail(item)">
                <WarningFilled />
              </el-icon>
            </template>
          </div>
        </div>
      </div>
    </div>

    <div class="device-line" :class="{ active: active && showBox }"></div>
  </div>
</template>

<script setup lang="ts">
import { getDeviceAnnotationDetail } from '@/api';
import { getAnnotationJzAndVideoList } from '@/api/bvideo';
import { getAnnotationSensorList, getSensorHisValue } from '@/api/sensor';
import { useActiveObject } from '@/store/activeObject';
import { storeToRefs } from 'pinia';
import { computed, onMounted, ref, watch } from 'vue';
import { ElImage, ElIcon } from 'element-plus'
import { VideoPlay, CloseBold } from '@element-plus/icons-vue'
import { useAlarmStore } from '@/store/alarm'
import { useDialog } from '@/hooks/useDialog'
import VideoDetails from '@/views/DataView/bvideo/videoDetails.vue'
import SensorDetails from '@/views/DataView/sensor/sensorDetail/sensorDetail.vue'
import RoadDetail from '@/views/DataView/road/roadDetail/roadDetail.vue'
import { useAuthStore } from '@/store/auth'
import { WarningFilled } from '@element-plus/icons-vue'
import JcjkAlarmDetail from '@/views/DataView/alarm/jcjkAlarmDetail/index.vue'
import emiter from '@/utils/mitt';
import bFan from './b-fan.vue';

const BASE_URL = import.meta.env.BASE_URL
const props = defineProps({
  name: {
    type: String,
    default: ''
  },
  id: {
    type: String,
    required: true
  },
  detailDtos: {
    type: Array,
  }
})

const activeObjectStore = useActiveObject()
const { activeFilter, isHistoryTracking } = storeToRefs(activeObjectStore)

const devices = ref([])
onMounted(() => {
  devices.value = props.detailDtos?.map((item) => {
    return {
      deviceType: item.deviceType,
      deviceIdList: item.deviceIdList
    }
  })

  watch([() => sensorListFilter.value, () => historyParams.value], async ([arr, params]) => {
    if (globalParams.value.areaId && arr.length && params.startTime && params.endTime) {
      const arr1 = []
      arr.forEach((item) => {
        arr1.push(
          getSensorHisValue({ cdCode: item.cdCode, ...params })
        )
      })
      const res = await Promise.all(arr1)
      hisSensorList.value = res.map(data => {
        return data.data
      })
    }
  })
})

const alarmStore = useAlarmStore()
const { alarmList } = storeToRefs(alarmStore)
const alarms = computed(() => {
  if (modeParams.value.model === 'realtime') {
    return alarmList.value
  } else {
    return historyData.value.alarmList
  }
})

function isIconAlarm (ids) {
  const isAlarm = alarms.value.some((item) => ids.flat().includes(item.cdCode))
  return isAlarm
}

function getIcon (type) {
  switch (type) {
    case '001':
      return 'icon-jizhan'
    case '002':
      return 'icon-shebeichuanganqi'
    case '003':
      return 'icon-shexiangtou'
  }
}

function extractDifferentPart (baseStr, targetStr) {
  let i = 0;
  // 遍历直到找到不同的字符或任一字符串结束
  while (i < baseStr.length && i < targetStr.length && baseStr[i] === targetStr[i]) {
    i++;
  }
  // 截取目标字符串中不同的部分
  return targetStr.substring(i);
}

const obj = {
  '001': 'baseStation',
  '002': 'sensor',
  '003': 'camera',
}
function filterShow (type) {
  return !isHistoryTracking.value && activeFilter.value.includes(obj[type])
}

const showBox = computed(() => {
  if (globalParams.value.areaId && modeParams.value.model === 'backtracking' && sceneTypeList.value.length) {
    let has = props.detailDtos?.some(device => {
      if (device.deviceType === '002') {
        const deviceIdList = device.deviceIdList.filter((ids) => {
          return sceneTypeList.value.find((item) => ids.includes(item.cdCode))
        })
        if (deviceIdList.length) {
          setActive(true)
        }
        return deviceIdList.length
      }
    })
    return has
  } else {
    setActive(false)
    return !isHistoryTracking.value && devices.value?.some((item) => activeFilter.value.includes(obj[item.deviceType]))
  }
})

interface Info {
  name: string
  cameraList: any[]
  jzList: any[]
  sensorList: any[]
}

const info = ref<Info>({
  name: '',
  cameraList: [],
  jzList: [],
  sensorList: []
})
const interval = ref<number | null>(null)

const hisSensorList = ref([])
const sensorListFilter = computed(() => {
  if (globalParams.value.areaId) {
    const arr = info.value.sensorList.filter((item) => {
      const node = sceneTypeList.value.find((scene) => item.cdCode === scene.cdCode)
      return node
    })
    return arr
  } else {
    return info.value.sensorList
  }
})

async function handleMousemove () {
  if (info.value.name) return
  const [{ data }, { data: jzAndVideo }, { data: sensor }] = await Promise.all([
    getDeviceAnnotationDetail({ id: props.id }),
    getAnnotationJzAndVideoList(props.id),
    getAnnotationSensorList(props.id)
  ])
  info.value = data
  info.value.jzList = jzAndVideo.jzList
  info.value.cameraList = jzAndVideo.cameraList
  info.value.sensorList = sensor
}
const active = ref(false)
async function setActive (bolean: boolean) {
  if (bolean) {
    await handleMousemove()
  }
  active.value = bolean
}
function handleActiveChange () {
  setActive(true)
}

function handleClose () {
  setActive(false)
}

const { openDialog } = useDialog()
function showVideoDialog (item) {
  openDialog(item.cameraName, VideoDetails, item)
}

function showAreaDialog (item) {
  openDialog(item.areaName, RoadDetail, { ...item, active }, {
    width: 950,
    height: 400
  })
}
const authStore = useAuthStore()
const { globalParams, modeParams, historyData, sceneTypeList, historyParams } = storeToRefs(authStore)
function showSensorDialog (item) {
  if (globalParams.value.startTime && globalParams.value.endTime) {
    openDialog(item.areaLocation, SensorDetails, item, {
      width: 800,
      height: 430
    })
  } else {
    openDialog(item.areaLocation, SensorDetails, item)
  }
}
// 跳转到告警详情
function showAlarmDetail (item) {
  const alarm = alarms.value.find((node) => node.cdCode === item.cdCode)
  alarm.id = alarm.alarmId
  openDialog(`${item.areaName} · ${alarm.alarmTypeName}`, JcjkAlarmDetail, alarm, {
    width: 800,
    height: 430
  })
}

watch([() => active.value, () => showBox.value], ([active, showBox]) => {
  if (active && showBox) {
    interval.value = setInterval(() => {
      getSensorList()
    }, 30000)
  } else {
    clearInterval(interval.value as number)
  }
})

emiter.on('timeSeek', () => {
  if (active.value && showBox.value) {
    getSensorList()
  }
})

async function getSensorList () {
  const { data: sensor } = await getAnnotationSensorList(props.id)
  info.value.sensorList = sensor
}

defineExpose({
  setActive
})

</script>
<style scoped lang="scss">
.b-box {
  cursor: pointer;
  opacity: 0.4;
  transition: opacity 0.3s ease-in-out;
  pointer-events: all;

  .devices-icon {
    position: relative;
    display: flex;
    gap: calc(8px * var(--viewScale));
    background: hsl(162deg 93% 38% / 20%);
    padding: calc(8px * var(--viewScale));
    border-radius: calc(22px * var(--viewScale));

    .devices-icon-item {
      position: relative;
      font-size: calc(16px * var(--viewScale));
      transition: all 0.2s ease-in-out;
      position: relative;

      &:has(.isAlarm) {
        color: var(--el-color-danger)
      }

      &.isAlarm {
        position: absolute;
        top: 0;
        left: 0;
        font-size: calc(16px * var(--viewScale));
        animation: col 1s infinite ease-in-out;
      }

      &:not(:last-child) {
        padding-right: 8px;

        &::after {
          position: absolute;
          content: '';
          width: 1px;
          height: 80%;
          top: 10%;
          right: 0;
          background: var(--text-color);
          opacity: 0.5;
        }
      }
    }
  }

  &:hover {
    opacity: 1;
    z-index: 9999 !important;
  }

  &:hover .devices-icon>.devices-icon-item {
    font-size: 18px;
  }

  &:hover .devices-icon>.devices-icon-item>.isAlarm {
    font-size: 18px;
  }

  &:hover .devices-body {
    display: flex;
  }

  .devices-body {
    display: none;
    flex-direction: column;
    position: absolute;
    top: -80px;
    left: 50%;
    border-radius: 4px;
    z-index: 2;
    transform: translate(-50%, -100%);
    white-space: nowrap;
    background: #03b87a80;
    font-size: 16px;
    box-shadow: 0 0 5px #000;

    &.active {
      display: flex;
    }

    .devices-body-name {
      color: var(--text-color);
      background-color: rgb(0, 147, 96);
      padding: 4px;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .devices-content {
      display: flex;
      flex-direction: column;
      gap: 4px;
      pointer-events: all;
      padding: 4px;

      .devices-content-video {
        .devices-content-video-item {
          display: flex;
          justify-content: center;
          align-items: center;
          width: 240px;
          height: 100px;
          background-color: #000;
        }
      }

      .devices-content-sensor {
        background: rgb(0, 71, 53);
        padding: 4px;
        box-sizing: border-box;
        overflow: hidden;
        font-size: 14px;

        .devices-content-sensor-item {
          display: flex;
          justify-content: space-between;
          align-items: center;

          &.isAlarm {
            color: var(--el-color-danger);
          }

          &.isInlen {
            display: inline-block;
            margin-right: 10px;

            &:last-child {
              margin-right: 0;
            }
          }

          .devices-content-sensor-item-name {
            margin-right: 8px;
            flex: 1;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
          }

          .el-icon {
            margin-left: 8px;
          }
        }
      }

      .devices-content-baseStation {
        background: rgb(0, 71, 53);
        padding: 12px 10px;
        box-sizing: border-box;
        width: 240;

        .devices-content-baseStation-item {
          display: flex;
          justify-content: space-between;

          .devices-content-baseStation-item-name {
            margin-right: 8px;
          }

          .devices-content-sensor-item-value {
            margin-left: 8px;
            flex: 1;
            overflow: hidden;
            text-overflow: ellipsis;
          }
        }
      }
    }
  }

  &:hover .device-line {
    display: block;
  }

  .device-line {
    display: none;
    position: absolute;
    top: -80px;
    left: calc(50% - 12px);
    height: 80px;
    width: 24px;
    padding: 8px 10px;
    border-radius: 50px;
    background: linear-gradient(180.00deg, rgba(0, 255, 167, 0.97), rgba(0, 247, 189, 0) 100%);
    background-clip: content-box;

    &.active {
      display: block;
    }
  }
}

.success {
  color: var(--el-color-success);
}

.error {
  color: var(--el-color-danger);
}

.warning {
  color: var(--el-color-warning);
}

.icon-jizhan {
  color: #1affb2;
}

.icon-shebeichuanganqi {
  color: #fce310;
}

.icon-shexiangtou {
  color: #55ffef;
}

@keyframes col {
  0% {
    color: var(--el-color-danger);
    transform: scale(1);
    opacity: 1;
  }

  100% {
    color: var(--el-color-danger-light-8);
    transform: scale(3.5);
    opacity: 0;
  }
}
</style>
